package com.handinfo.android.uicontrols.controls;

import java.util.concurrent.CopyOnWriteArrayList;

import android.graphics.Bitmap;
import android.graphics.PointF;

import com.handinfo.android.core.graphics.DWGraphics;
import com.handinfo.android.ui.UIWindows;
import com.handinfo.android.utils.Tools;

/**
 * 内容列表控件
 * @author handinfo
 */
public class DWListbox extends DWControl
{

	private CopyOnWriteArrayList<DWListSubItem> m_items = new CopyOnWriteArrayList<DWListSubItem>();
	private int m_touch_index = -1;//触摸的索引
	private float m_offset_y = 0;
	private DWScrollBar m_scrollbar = null;
	private int m_line_spacing = 0;
	private boolean m_is_draw_rect = true;//是否绘制选择背景
	private boolean m_is_bottom = false;//是否自动滚动到最底下
	private Bitmap img_select = null;

	public DWListbox(int w, int h)
	{
		setShowWideHigh(w, h);
		img_select = UIWindows.createImage("/img/newui/xuanzekuang_1.gnp");
	}

	public void render(DWGraphics g)
	{
		g.setClip(m_show_x, m_show_y, m_show_w + 1, m_show_h + 1);
		DWListSubItem subItem = null;
		m_deviant_y = (int) m_offset_y;
		for (int i = 0; i < m_items.size(); i++) {
			subItem = m_items.get(i);
			if (m_is_draw_rect && i == m_touch_index) {
				g.setClip(m_show_x, m_show_y, m_show_w + 1, m_show_h + 1);
				renderSelectRect(g, subItem, m_show_x, m_show_y, (int)m_deviant_x, (int)m_deviant_y);
			}
			subItem.renderLimits(g, m_show_x, m_show_y, m_show_w, m_show_h, (int)m_deviant_x, (int)m_deviant_y);
		}
		renderRect(g);
		if (m_scrollbar != null) {
			m_scrollbar.render(g);
		}
		renderGuide(g);
	}

	public void renderLimits(DWGraphics g, int x, int y, int w, int h, int offsetx, int offsety)
	{
		setSubClip(g, x, y, w, h, offsetx, offsety);
		DWListSubItem subItem = null;
		m_deviant_y = (int) m_offset_y;
		for (int i = 0; i < m_items.size(); i++) {
			subItem = m_items.get(i);
			if (m_is_draw_rect && i == m_touch_index) {
				setSubClip(g, x, y, w, h, offsetx, offsety);
				renderSelectRect(g, subItem, x + m_show_x, y + m_show_y, offsetx + (int)m_deviant_x, offsety + (int)m_deviant_y);
			}
			subItem.renderLimits(g, x + m_show_x, y + m_show_y, m_show_w, m_show_h, offsetx + (int)m_deviant_x, offsety + (int)m_deviant_y);
		}
		renderLimitsRect(g, x, y, offsetx, offsety);
		if (m_scrollbar != null) {
			m_scrollbar.setDefaultNearAnchor();
			m_scrollbar.renderLimits(g, x, y, w, h, offsetx, offsety);
		}
		renderGuide(g, (int)(x - offsetx - m_deviant_x), (int)(y - offsety - m_deviant_y));
	}
	
	private void renderSelectRect(DWGraphics g, DWListSubItem lsi, int x, int y, int offsetx, int offsety) {
		g.setColor(0x88000080);
//		g.fillRect(x + lsi.getShowX() - offsetx, y + lsi.getShowY() - offsety, lsi.getShowWidth(), lsi.getShowHeight());
		g.drawBitmap(img_select, x + lsi.getShowX() - offsetx, y + lsi.getShowY() - offsety, lsi.getShowWidth(), lsi.getShowHeight(), Tools.LEFT_TOP);
	}
	/**
	 * 设置是否显示到最底部
	 * @param bottom
	 */
	public void setBottom(boolean bottom) {
		m_is_bottom = bottom;
	}
	
	/**
	 * 立即对listbox置底
	 */
	public void setDown() {
		if (m_actual_h > m_show_h) {
			m_offset_y = m_actual_h - m_show_h;
		}
		if (m_scrollbar != null) {
			m_scrollbar.setMark((int)(m_offset_y * 100 / (m_actual_h - m_show_h)));
		}
	}
	
	/**
	 * 设置每个ListSubItem之间的间距
	 * @param spacing
	 */
	public void setLineSpacing(int spacing) {
		m_line_spacing = spacing;
	}
	
	/**
	 * 设置是否显示选中时的背景条
	 * @param show
	 */
	public void setShowBackgroundRect(boolean show) {
		m_is_draw_rect = show;
	}
	
	/**
	 * 设置滚动条
	 * @param index
	 */
	public void setScrollbar(int index) {
		if (m_scrollbar != null && m_actual_h > m_show_h) {
			m_offset_y = index * m_actual_h / m_items.size();
			if (m_offset_y < 0) {
				m_offset_y = 0;
			}
			else if (m_offset_y + m_show_h > m_actual_h) {
				m_offset_y = m_actual_h - m_show_h;
			}
			if (m_scrollbar != null) {
				m_scrollbar.setMark((int) (m_offset_y * 100 / (m_actual_h - m_show_h)));
			}
		}
	}

	public void addSubItem(DWListSubItem subItem)
	{
		setRelyControl(this);

		if (m_items.size() == 0) {
			subItem.setNearAnchor(this, Tools.LEFT_TOP, Tools.LEFT_TOP, 0, m_line_spacing / 2);
			subItem.setPoint(subItem.m_show_x - m_show_x, subItem.m_show_y - m_show_y);
		} else {
			subItem.setNearAnchor(m_items.get(m_items.size() - 1), Tools.LEFT_TOP, Tools.LEFT_BOTTOM, 0, m_line_spacing);
		}
		
		subItem.refreshControl();
		
		boolean update = false;
		if (m_actual_h > m_show_h && m_is_bottom) {
			update = true;
		}
		
		if (m_actual_h > m_show_h && m_offset_y == m_actual_h - m_show_h) {
			update = true;
		}
		
		m_actual_h += (subItem.m_show_h + m_line_spacing);
		if (m_actual_w < subItem.m_show_w) {
			m_actual_w = subItem.m_show_w;
		}
		
		m_items.add(subItem);
		updateScrollbar(update);
	}

	public void refreshControl()
	{
		DWListSubItem lsi = null;
		for (int i = 0; i < m_items.size(); i++) {
			lsi = m_items.get(i);
			if (i == 0) {
				lsi.setNearAnchor(this, Tools.LEFT_TOP, Tools.LEFT_TOP, 0, m_line_spacing / 2);
			} else {
				lsi.setNearAnchor(m_items.get(i - 1), Tools.LEFT_TOP, Tools.LEFT_BOTTOM, 0, m_line_spacing);
			}
		}
		m_actual_h = 0;
		m_actual_w = 0;
		for (int i = 0; i < m_items.size(); i++) {
			lsi = m_items.get(i);
			lsi.setPoint(lsi.m_show_x - m_show_x, lsi.m_show_y - m_show_y);
			lsi.refreshControl();
			m_actual_h += (lsi.m_show_h + m_line_spacing);
			if (m_actual_w < lsi.m_show_w) {
				m_actual_w = lsi.m_show_w;
			}
		}
		
		boolean update = false;
		if (m_actual_h > m_show_h && m_is_bottom) {
			update = true;
		}
		updateScrollbar(update);
	}

	/**
	 * 移除当前下标对应的子项
	 * @param index
	 */
	public void removeSubItem(int index)
	{
		if (index > -1 && index < m_items.size()) {
			m_items.remove(index);
			refreshControl();
		}
	}
	
	/**
	 * 移除此子项
	 * @param subItem
	 */
	public void removeSubItem(DWListSubItem subItem)
	{
		if (subItem != null) {
			if (m_items.remove(subItem)) {
				refreshControl();
			}
		}
	}

	/**
	 * 移除列表中所有子项
	 */
	public void removeAllSubItem()
	{
		m_items.clear();
		m_offset_y = 0;
		setActualWideHigh(0, 0);
		if (m_scrollbar != null) {
			m_scrollbar.destroy();
			m_scrollbar = null;
		}
	}
	/**
	 * 删除一个SubItem内的控件
	 * @param index
	 * @param subIndex
	 */
	public void removeSubItemControl(int index, int subIndex) {
		if (index > -1 && index < m_items.size()) {
			m_items.get(index).removeControl(subIndex);
			refreshControl();
		}
	}
	/**
	 * 删除一个SubItem内的控件
	 * @param index
	 * @param subControl
	 */
	public void removeSubItemControl(int index, DWListSubItem subControl) {
		if (index > -1 && index < m_items.size()) {
			if (m_items.get(index).removeControl(subControl)) {
				refreshControl();
			}
		}
	}
	/**
	 * 删除一个SubItem内的控件
	 * @param control
	 * @param subIndex
	 */
	public void removeSubItemControl(DWListSubItem control, int subIndex) {
		if (m_items.contains(control)) {
			if (control.removeControl(subIndex) != null) {
				refreshControl();
			}
		}
	}
	/**
	 * 删除一个SubItem内的控件
	 * @param control
	 * @param subControl
	 */
	public void removeSubItemControl(DWListSubItem control, DWControl subControl) {
		if (m_items.contains(control)) {
			if (control.removeControl(subControl)) {
				refreshControl();
			}
		}
	}
	
	private void updateScrollbar(boolean update) {
		if (m_offset_y < 0) {
			m_offset_y = 0;
		}
		else if (m_actual_h > m_show_h) {
			if (m_offset_y + m_show_h > m_actual_h) {
				m_offset_y = m_actual_h - m_show_h;
			}
		}
		if (m_actual_h > m_show_h) {
			if (m_scrollbar == null) {
				m_scrollbar = new DWScrollBar(m_show_h);
				m_scrollbar.setNearAnchor(this, Tools.LEFT_TOP, Tools.RIGHT_TOP, 2, 0);
			}
			if (update) {
				m_offset_y = m_actual_h - m_show_h;
				m_scrollbar.setMark((int) (m_offset_y * 100 / (m_actual_h - m_show_h)));
			}
		} else {
			m_offset_y = 0;
			if (m_scrollbar != null) {
				m_scrollbar.destroy();
				m_scrollbar = null;
			}
		}
	}

	public void logic()
	{
		for (int i = 0; i < m_items.size(); i++) {
			m_items.get(i).logic();
		}
	}
	/**
	 * 得到listbox子类
	 * @param index
	 * @return
	 */
	public DWListSubItem getListSubItem(int index) {
		return m_items.get(index);
	}

	/**
	 * 得到子类长度
	 * @return
	 */
	public int getSubItemSize() {
		return m_items.size();
	}
	/**
	 * 得到触摸的下标
	 * @return
	 */
	public int getTouchIndex()
	{
		return m_touch_index;
	}
	/**
	 * 设置触摸下标
	 * @param index
	 */
	public void setTouchIndex(int index) {
		m_touch_index = index;
	}
	public boolean doLongPress(PointF point) {
		if (checkPointOnRect(point.x, point.y)) {
			PointF newPoint = new PointF(point.x - m_show_x, point.y - m_show_y + m_offset_y);
			for (int i = 0; i < m_items.size(); i++) {
				if (m_items.get(i).doLongPress(newPoint)) {
					return true;
				}
			}
		}
		return false;
	}
	public boolean doDown(PointF point)
	{
		if (checkPointOnRect(point.x, point.y)) {
			PointF newPoint = new PointF(point.x - m_show_x, point.y - m_show_y + m_offset_y);
			for (int i = 0; i < m_items.size(); i++) {
				if (m_items.get(i).doDown(newPoint)) {
					return true;
				}
			}
		}
		return false;
	}
	
	public boolean doDrag(PointF start, PointF end, float velocityX, float velocityY)
	{
		if (checkPointOnRect(end.x, end.y)) {
			PointF newStart = new PointF(start.x - m_show_x, start.y - m_show_y + m_offset_y);
			PointF newEnd = new PointF(end.x - m_show_x, end.y - m_show_y + m_offset_y);
			for (int i = 0; i < m_items.size(); i++) {
				if (m_items.get(i).doDrag(newStart, newEnd, velocityX, velocityY)) {
					return true;
				}
			}
		}
		return false;
	}
	
	public boolean doFling(PointF start, PointF end, float velocityX, float velocityY)
	{
		if (checkPointOnRect(end.x, end.y)) {
			PointF newStart = new PointF(start.x - m_show_x, start.y - m_show_y + m_offset_y);
			PointF newEnd = new PointF(end.x - m_show_x, end.y - m_show_y + m_offset_y);
			for (int i = 0; i < m_items.size(); i++) {
				if (m_items.get(i).doFling(newStart, newEnd, velocityX, velocityY)) {
					return true;
				}
			}
		}
		return false;
	}

	public boolean doClick(float x, float y)
	{
		if (checkPointOnRect(x, y)) {
			setGuide(false);
			m_deviant_y = (int) m_offset_y;
			DWListSubItem lsi = null;
			for (int i = 0; i < m_items.size(); i++) {
				lsi = m_items.get(i);
				boolean result = false;
				if (lsi.checkPointOnRect(x - m_show_x, y - m_show_y + m_deviant_y)) {
					m_touch_index = i;
					if (m_listener != null) {
						m_listener.OnClick();
					}
					result = true;
				}
				if (lsi.doClick(x - m_show_x, y - m_show_y + m_deviant_y)) {
					result = true;
				}
				if (result) {
					return true;
				}
			}
		}
		return false;
	}

	public boolean doScroll(PointF start, PointF end, float distanceX, float distanceY)
	{
		if (checkPointOnRect(start.x, start.y)) {
			DWListSubItem lsi = null;
			PointF newStart = new PointF(start.x - m_show_x, start.y - m_show_y + m_offset_y);
			PointF newEnd = new PointF(end.x - m_show_x, end.y - m_show_y + m_offset_y);
			for (int i = 0; i < m_items.size(); i++) {
				lsi = m_items.get(i);
				if (lsi.doScroll(newStart, newEnd, distanceX, distanceY)) {
					return true;
				}
			}
			if (m_actual_h > m_show_h) {
//				float b = m_actual_h / m_show_h;
				m_offset_y += distanceY;
				if (m_offset_y < 0) {
					m_offset_y = 0;
				}
				else if (m_offset_y + m_show_h > m_actual_h) {
					m_offset_y = m_actual_h - m_show_h;
				}
				if (m_scrollbar != null) {
					m_scrollbar.setMark((int) (m_offset_y * 100 / (m_actual_h - m_show_h)));
				}
			}
			return true;
		}
		return false;
	}

}
